#include <iostream>
#include "MessageParser.hpp"
#include "stringlogger.hpp"
#include <iterator>
Message MessageParser::parse(const Data& rawMsg)
{
	Message retval;
	Data payload;
	std::back_insert_iterator<Data> payloadInserter(payload);

	unsigned int messageLength = m_headerParser.getMessageLength(rawMsg);
	unsigned int headerLength = m_headerParser.getHeaderLength(rawMsg);
	unsigned int payloadStart = m_headerParser.getMsgDataStart(rawMsg);
	retval.setAddresses(m_headerParser.getMsgAddresses(rawMsg));

    std::copy(rawMsg.begin()+headerLength, rawMsg.begin()+messageLength+headerLength-1, payloadInserter);
	retval.setPayload(payload);
    validateChecksum(rawMsg, messageLength+headerLength-1);
    retval.addHeader();
	return retval;
}

char MessageParser::getSid(const Data& p_msg, unsigned int startPos)
{
    LOG << "Sid: " << p_msg[startPos] << "\n";
    return p_msg[startPos];
}
Data MessageParser::getMessageData(const Data& p_msg)
{
    try
    {
        validateChecksum(p_msg, p_msg.size()-1);
        size_t start = m_headerParser.getMsgDataStart(p_msg);
        char sid = getSid(p_msg, start);//Service Identifier (command)
        return decodeMessageDataToHumanReadable(p_msg, start);

    }
    catch(const char* exception)
    {
        LOG << exception;
    }
    return Data();
}
void MessageParser::validateChecksum(const Data& p_msg, unsigned int checksumPos) const
{
	if(checksumPos > p_msg.size()-1)
		throw "incomplete message, where's my checksum?";
    unsigned char checksum(0);
    for(size_t i=0;i<checksumPos;++i)
    {
        checksum = checksum + p_msg[i];
    }
    checksum %= 256;
    if(checksum != p_msg[checksumPos])
    {
        throw "Invalid Message checksum";
    }
}

Data MessageParser::decodeMessageDataToHumanReadable(const Data& p_msg, size_t startPos)
{
    //lazy implementation

    return Data(p_msg.begin()+startPos, p_msg.end()-1);
}

bool MessageParser::isValidMessageAvaliable(const Data& p_msg)
{
    unsigned int messageLength = m_headerParser.getMessageLength(p_msg);
    if(p_msg.size()<messageLength+1)
        return false;
    return true;
}
